package com.tsin.usercenter.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tsin.usercenter.common.ErrorCode;
import com.tsin.usercenter.exception.BusinessException;
import com.tsin.usercenter.mapper.UserteamMapper;
import com.tsin.usercenter.model.Team;
import com.tsin.usercenter.model.User;
import com.tsin.usercenter.model.Userteam;
import com.tsin.usercenter.model.dto.TeamQuery;
import com.tsin.usercenter.model.dto.TeamUpdateQuery;
import com.tsin.usercenter.model.eumn.TeamStatusEnum;
import com.tsin.usercenter.model.request.JoinTeamRequest;
import com.tsin.usercenter.model.request.QuitTeamRequest;
import com.tsin.usercenter.model.request.TeamRequest;
import com.tsin.usercenter.model.vo.TeamVO;
import com.tsin.usercenter.model.vo.UserVO;
import com.tsin.usercenter.service.TeamService;
import com.tsin.usercenter.mapper.TeamMapper;
import com.tsin.usercenter.service.UserService;
import com.tsin.usercenter.service.UserteamService;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
 * @author tsin0
 * @description 针对表【team】的数据库操作Service实现
 * @createDate 2024-01-13 14:27:24
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class TeamServiceImpl extends ServiceImpl<TeamMapper, Team>
        implements TeamService {

    @Resource
    private TeamMapper teamMapper;
    @Resource
    private UserteamService userteamService;

    @Resource
    private UserService userService;

    @Resource
    private UserteamMapper userteamMapper;


    @Override
    public long addTeam(TeamRequest teamRequest, User loginUser) {
        Team team = new Team();
        BeanUtils.copyProperties(teamRequest, team);
        //1.请求参数是否为空
        if (team == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        //2.是否登录
        if (loginUser == null) {
            throw new BusinessException(ErrorCode.NOT_LOGIN);
        }
        //3.校验信息
        //3.1队伍人数>=1且<=20
        int teamMaxnumber = Optional.ofNullable(team.getTeamMaxnumber()).orElse(0);
        if (teamMaxnumber > 20) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "队伍人数可能超过上限（20）");
        }
        //3.2队伍标题
        String teamName = team.getTeamName();
        if (teamName == null || teamName.length() > 16) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "队伍名称可能超过上限（16）或为空");
        }
        //队伍简介不超过100字
        String teamDescription = team.getTeamDescription();
        if (teamDescription.length() > 100) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "队伍名称可能超过上限（100）");
        }
        //队伍状态检查（0-公开 1-私有 2-加密）
        Integer teamStatus = Optional.ofNullable(team.getTeamStatus()).orElse(0);
        TeamStatusEnum enumByValue = TeamStatusEnum.getEnumByValue(teamStatus);
        if (enumByValue == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "队伍状态非法");
        }
        //如果是加密的队伍，需要校验密码
        String teamPassword = team.getTeamPassword();
        if (enumByValue.equals(TeamStatusEnum.SECRET)) {
            if (StringUtils.isBlank(teamPassword) || teamPassword.length() != 12)
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "队伍邀请码错误(1)");
        }
        //如果不是加密队伍，不需要输入密码
        if (enumByValue.equals(TeamStatusEnum.PUBLIC) || enumByValue.equals(TeamStatusEnum.PRIVATE)) {
            if (StringUtils.isNotBlank(teamPassword))
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "队伍邀请码错误(2)");
        }
        //超时时间>当前时间
        Date expireTime = team.getTeamExpiretime();
        if (new Date().after(expireTime)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "超时时间 > 当前时间");
        }
        //每个用户最多5个队伍
        Long userId = loginUser.getId();
        QueryWrapper<Team> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        long teamCountById = this.count(queryWrapper);
        if (teamCountById > 5) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户创建队伍已达到最大数(5)");
        }
        //插入队伍信息到队伍表
        team.setUserId(userId);
        team.setCreateTime(new Date());
        boolean saveToTeam = this.save(team);
        if (!saveToTeam) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR);
        }
        //插入队伍信息到队伍信息表
        Userteam userteam = new Userteam();
        userteam.setUserId(userId);
        userteam.setTeamId(team.getId());
        userteam.setJoinTime(new Date());
        boolean saveToUserTeam = userteamService.save(userteam);
        if (!saveToUserTeam) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR);
        }
        return team.getId();
    }

    @Override
    public List<TeamVO> listTeams(TeamQuery teamQuery) {
        QueryWrapper<Team> queryWrapper = new QueryWrapper<>();
        // 组合查询条件
        if (teamQuery != null) {

            Long id = teamQuery.getId();
            if (id != null && id > 0) {
                queryWrapper.eq("id", id);
            }
            String name = teamQuery.getTeamName();
            if (StringUtils.isNotBlank(name)) {
                queryWrapper.like("team_name", name);
            }
            String description = teamQuery.getTeamDescription();
            if (StringUtils.isNotBlank(description)) {
                queryWrapper.like("team_description", description);
            }
            Integer maxNum = teamQuery.getTeamMaxnumber();
            // 查询最大人数相等的
            if (maxNum != null && maxNum > 0) {
                queryWrapper.eq("team_maxnumber", maxNum);
            }
            Long userId = teamQuery.getUserId();
            // 根据创建人来查询
            if (userId != null && userId > 0) {
                queryWrapper.eq("user_id", userId);
            }
            // 根据状态来查询
            Integer status = teamQuery.getTeamStatus();
            if (status != null && (status > 0 && status <= 2)) {
                queryWrapper.eq("team_status", status);
            }
        }
        List<Team> list = this.list(queryWrapper);
        if (CollectionUtils.isEmpty(list)) {
            return new ArrayList<>();
        }
        //关联查询用户信息
        ArrayList<TeamVO> teamVOS = new ArrayList<>();
        for (Team team : list) {
            if (new Date().after(team.getTeamExpiretime())) {
                continue;
            }
            TeamVO teamVO = new TeamVO();
            UserVO userVO = new UserVO();
            Long userIdFromTeam = team.getUserId();
            User userById = userService.getById(userIdFromTeam);
            BeanUtils.copyProperties(userById, userVO);
            BeanUtils.copyProperties(team, teamVO);
            teamVO.setCreateUser(userVO);
            teamVOS.add(teamVO);
        }
        return teamVOS;
    }

    @Override
    public Boolean updateTeam(TeamUpdateQuery teamUpdateQuery, User loginUser) {
        QueryWrapper<Team> teamQueryWrapper = new QueryWrapper<>();
        if (teamUpdateQuery == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        String teamName = teamUpdateQuery.getTeamName();
        Long id = teamUpdateQuery.getId();
        String teamDescription = teamUpdateQuery.getTeamDescription();
        Integer teamStatus = Optional.ofNullable(teamUpdateQuery.getTeamStatus()).orElse(0);
        TeamStatusEnum enumByValue = TeamStatusEnum.getEnumByValue(teamStatus);
        String teamPassword = teamUpdateQuery.getTeamPassword();
        //输入是否非法判断
        //2.是否登录
        //2.是否登录
        if (loginUser == null) {
            throw new BusinessException(ErrorCode.NOT_LOGIN);
        }
        Long loginUserId = loginUser.getId();
        //id非空且大于0
        if (id == null || id <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        //3.2队伍标题
        if (teamName == null || teamName.length() > 16) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "队伍名称可能超过上限（16）或为空");
        }
        //队伍简介不超过100字
        if (teamDescription.length() > 100) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "队伍名称可能超过上限（100）");
        }
        //队伍状态检查（0-公开 1-私有 2-加密）
        if (enumByValue == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "队伍状态非法");
        }
        //如果是加密的队伍，需要校验密码
        if (enumByValue.equals(TeamStatusEnum.SECRET)) {
            if (StringUtils.isBlank(teamPassword) || teamPassword.length() != 12)
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "队伍邀请码错误(1)");
        }
        //如果不是加密队伍，不需要输入密码
        if (enumByValue.equals(TeamStatusEnum.PUBLIC) || enumByValue.equals(TeamStatusEnum.PRIVATE)) {
            if (StringUtils.isNotBlank(teamPassword))
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "队伍邀请码错误(2)");
        }
        teamQueryWrapper.eq("id", id);
        teamQueryWrapper.eq("user_id", loginUserId);
        Team team = teamMapper.selectOne(teamQueryWrapper);
        if (team == null) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR);
        }
        if (teamUpdateQuery.getTeamStatus() == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "状态为空");
        }
        BeanUtils.copyProperties(teamUpdateQuery, team);
        return this.updateById(team);
    }

    @Override
    public Boolean deleteTeam(int id, User loginUser) {
        //参数判空
        if (id < 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数错误");
        }
        //登录用户信息判空
        if (loginUser == null) {
            throw new BusinessException(ErrorCode.NOT_LOGIN);
        }
        //判断是否有权限删除
        Long loginUserId = loginUser.getId();
        QueryWrapper<Team> teamQueryWrapper = new QueryWrapper<>();
        teamQueryWrapper.eq("user_id", loginUserId);
        teamQueryWrapper.eq("id", id);
        Team team = teamMapper.selectOne(teamQueryWrapper);
        //查询team数据库是否有需要删除的数据(id,userId)
        if (team == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数错误");
        }
        //删除team数据库&&删除userteam数据库的数据
        QueryWrapper<Userteam> userteamQueryWrapper = new QueryWrapper<>();
        userteamQueryWrapper.eq("team_id", id);
//        if(userteamQueryWrapper==null){
//            throw new BusinessException(ErrorCode.PARAMS_ERROR,"参数错误");
//        }
        boolean resultTeam = this.removeById(team);
        boolean resultUserTeam = userteamService.remove(userteamQueryWrapper);
        if (!resultTeam) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "删除事务发生错误");
        }
        if (!resultUserTeam) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "删除事务发生错误");
        }
        return true;
    }

    public Boolean joinTeams(JoinTeamRequest joinTeamRequest, User loginUser) {
        //参数判空
        int team_id = joinTeamRequest.getId();
        if (team_id < 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数错误");
        }
        Team teamById = this.getById(team_id);
        if (teamById == null) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR);
        }
        //登录用户信息判空
        if (loginUser == null) {
            throw new BusinessException(ErrorCode.NOT_LOGIN);
        }
        //群未过期的
        Date teamExpiretime = teamById.getTeamExpiretime();
        //超时时间>当前时间
        if (new Date().after(teamExpiretime)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "超时时间 > 当前时间");
        }
        //用户最多加入10个
        Long loginUserId = loginUser.getId();
        QueryWrapper<Userteam> userteamQueryWrapper = new QueryWrapper<>();
        userteamQueryWrapper.eq("user_id", loginUserId);
        Long UserInTeamNumber = userteamMapper.selectCount(userteamQueryWrapper);
        System.out.println("该用户加入的群共" + UserInTeamNumber + "个");
        if (UserInTeamNumber >= 10) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "你的队伍数量已经达到上限");
        }
        //群人数<=10
        long usersInTeamCount = countTeamUserByTeamId(team_id);
        System.out.println("群人数为" + usersInTeamCount);
        if (usersInTeamCount >= 10) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "群聊已满");
        }
        //只可以加入公开或加密的
        //队伍状态检查（0-公开 1-私有 2-加密）
        Integer teamStatus = Optional.ofNullable(teamById.getTeamStatus()).orElse(0);
        TeamStatusEnum enumByValue = TeamStatusEnum.getEnumByValue(teamStatus);
        if (enumByValue.equals(TeamStatusEnum.PRIVATE)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "队伍不允许加入");
        }
        //如果不是加密队伍，不需要输入密码
        //加密的要输入密码
        if (enumByValue.equals(TeamStatusEnum.SECRET)) {
            String Password = joinTeamRequest.getTeamPassword();
            String teamPassword = teamById.getTeamPassword();
            if (!Password.equals(teamPassword)) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数错误");
            }
        }
        //不能重复加入
        long existInTeamCount = isExistInTeam(team_id, loginUserId);
        if (existInTeamCount > 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "你已经在队伍中");
        }
        Userteam userteam = new Userteam();
        userteam.setUserId(loginUserId);
        userteam.setTeamId(team_id);
        userteam.setJoinTime(new Date());
        userteam.setCreateTime(new Date());
        return userteamService.save(userteam);
    }

    @Override
    public Boolean quitTeams(QuitTeamRequest quitTeamRequest, User loginUser) {
        if (quitTeamRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        //登录用户信息判空
        if (loginUser == null) {
            throw new BusinessException(ErrorCode.NOT_LOGIN);
        }
        //校验队伍是否存在
        Integer teamId = quitTeamRequest.getId();
        Team teamById = this.getById(teamId);
        if (teamById == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "队伍不存在");
        }
        //获取当前群聊中是否已存在某个用户的数量
        Long userId = loginUser.getId();
        List<Userteam> existInTeamList = isExistInTeamList(teamId, userId);
        if (existInTeamList.size() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "已退出群聊，不可重复操作");
        }
        //判断是否是队长
        QueryWrapper<Userteam> userTeamQueryWrapper = new QueryWrapper<>();
        userTeamQueryWrapper.eq("team_id", teamId);
        userTeamQueryWrapper.last("order by id asc limit 2");
        List<Userteam> userTeamList = userteamService.list(userTeamQueryWrapper);
        Userteam headderUserTeam = userTeamList.get(0);
        if (headderUserTeam.getUserId().equals(userId)) {
            boolean remove = userteamService.removeById(headderUserTeam);
            if (!remove) {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR);
            }
            if(userTeamList.size()==1){
                boolean teamB = this.removeById(teamById);
                if(!teamB){
                    throw new BusinessException(ErrorCode.SYSTEM_ERROR);
                }
            }
            if(userTeamList.size()>1){
                Userteam headderUserTeam2 = userTeamList.get(1);
                teamById.setUserId(headderUserTeam2.getUserId());
                boolean update = this.updateById(teamById);
                if (!update) {
                    throw new BusinessException(ErrorCode.SYSTEM_ERROR);
                }
            }
        } else {
            Userteam userteam = existInTeamList.get(0);
            boolean remove = userteamService.removeById(userteam);
            if (!remove) {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR);
            }
        }
        List<Userteam> userteams = TeamUserByTeamIdList(teamId);
        Userteam userteam0 = null;
        if(!userteams.isEmpty()){
            userteam0 = userteams.get(0);
            if (userteam0 == null) {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR);
            }
        }
        if (userteams.size() == 1) {
            boolean b0 = userteamService.removeById(userteam0);
            if (!b0) {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR);
            }
            boolean b1 = this.removeById(teamId);
            if (!b1) {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR);
            }
        }
        return true;
    }

    @Override
    public List<Team> getMyTeam(User loginUser) {
        //登录用户信息判空
        if (loginUser == null) {
            throw new BusinessException(ErrorCode.NOT_LOGIN);
        }
        Long userId = loginUser.getId();
        QueryWrapper<Userteam> userteamQueryWrapper = new QueryWrapper<>();
        userteamQueryWrapper.eq("user_id",userId);
        List<Userteam> userteams = userteamMapper.selectList(userteamQueryWrapper);
        if(userteams==null){
            throw new BusinessException(ErrorCode.SYSTEM_ERROR);
        }
        ArrayList<Team> teams = new ArrayList<>();
        for (Userteam userteam :userteams) {
            Integer teamId = userteam.getTeamId();
            Team teamById = this.getById(teamId);
            teams.add(teamById);
        }
        return teams;
    }

    //获取某队伍当前人数
    private long countTeamUserByTeamId(long teamId) {
        QueryWrapper<Userteam> userTeamQueryWrapper = new QueryWrapper<>();
        userTeamQueryWrapper.eq("team_id", teamId);
        return userteamService.count(userTeamQueryWrapper);
    }

    //获取某队伍当前人数
    private List<Userteam> TeamUserByTeamIdList(long teamId) {
        QueryWrapper<Userteam> userTeamQueryWrapper = new QueryWrapper<>();
        userTeamQueryWrapper.eq("team_id", teamId);
        return userteamService.list(userTeamQueryWrapper);
    }

    //获取当前群聊中是否已存在某个用户的数量
    private long isExistInTeam(long teamId, long userId) {
        QueryWrapper<Userteam> userTeamQueryWrapper = new QueryWrapper<>();
        userTeamQueryWrapper.eq("team_id", teamId);
        userTeamQueryWrapper.eq("user_id", userId);
        return userteamService.count(userTeamQueryWrapper);
    }

    private List<Userteam> isExistInTeamList(long teamId, long userId) {
        QueryWrapper<Userteam> userTeamQueryWrapper = new QueryWrapper<>();
        userTeamQueryWrapper.eq("team_id", teamId);
        userTeamQueryWrapper.eq("user_id", userId);
        return userteamService.list(userTeamQueryWrapper);
    }

    //校验队伍是否存在
    private long isExistTeam(long teamId) {
        QueryWrapper<Team> teamQueryWrapper = new QueryWrapper<>();
        teamQueryWrapper.eq("id", teamId);
        return this.count(teamQueryWrapper);
    }

}




